-module(average).
-export([addFragmentsToAvgStruct/3, new/0, start/3, getSum/1, getCount/1, getFragmentIds/1]).
-import(erlang, [display/1]).

start(Id, Neighbors, AvgStruct) ->
  random:seed(now()),
	case gossipprob:getGossipNode(Neighbors) of
	  {ok, Node} ->
			Node ! {avg, AvgStruct};
		{error, _Msg} ->
		ok
	end,
	ok.	

addFragmentsToAvgStruct([], _Dict, AvgStruct) ->
  AvgStruct;
addFragmentsToAvgStruct(Keys, Dict, AvgStruct) ->
  FragId = hd(Keys),
  case hasFragmentId(FragId, AvgStruct) of
    false ->
      FloatList = dict:fetch(FragId, Dict),
      NAS1 = incrSum(lists:sum(FloatList), AvgStruct),
      NAS2 = incrCount(length(FloatList), NAS1),
      NewAvgStruct = addFragmentId(FragId, NAS2);
    true ->
      NewAvgStruct = AvgStruct
  end,
    addFragmentsToAvgStruct(tl(Keys), Dict, NewAvgStruct).
    
%Struct is a tuple that contains Sum, Count, FragmentIds
new() ->
  {0, 0, []}.
  
getSum(AvgStruct) ->
  element(1, AvgStruct).
  
getCount(AvgStruct) ->
  element(2, AvgStruct).
  
getFragmentIds(AvgStruct) ->
  element(3, AvgStruct).
  
incrSum(Num, AvgStruct) ->
  {getSum(AvgStruct) + Num, getCount(AvgStruct), getFragmentIds(AvgStruct) }.

incrCount(Num, AvgStruct) ->
  {getSum(AvgStruct), getCount(AvgStruct) + Num, getFragmentIds(AvgStruct) }.

hasFragmentId(Id, AvgStruct) ->
  lists:member(Id, getFragmentIds(AvgStruct)).
  
addFragmentId(Id, AvgStruct) ->
  {getSum(AvgStruct), getCount(AvgStruct), [ Id | getFragmentIds(AvgStruct) ]}.
  
